package org.rency.common.utils.security;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

/**
 * RSA加密解密算法(非对称)
 * @author: user_rcy@163.com
 * </br>Created on 2016年4月20日
 * @version: V1.0.0
 * @since JDK 1.8
 */
public class RSAUtils {
	
	private static final String KEY_ALGORITHM = "RSA";//加密算法RSA
	private static final int KEY_LENGTH = 1024;//密钥长度
	
	/**
	 * 生成密钥对(公钥和私钥)
	 * </br>Created on 2016年4月20日
	 * @return
	 * @throws Exception
	 */
    public static KeyPair genKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(KEY_LENGTH);
        return keyPairGen.generateKeyPair();
    }
    
    /**
     * 将RSA公钥密钥转换为字符串(62位)
     * </br>Created on 2016年4月20日
     * @param key
     * @return
     */
    @SuppressWarnings("static-access")
	public static String getRSAKeyToString(Key key){
    	byte[] keyBytes = key.getEncoded();
    	String s = (new Base64Utils()).encoder(keyBytes);
        return s;
    }
	
	/**
	 * RSA公钥加密
	 * </br>Created on 2016年4月20日
	 * @param content
	 * @param publicKey
	 * @return
	 * @throws Exception
	 */
	public static String encryptRSAWithPublicKey(String content,String publicKey) throws Exception{
		try{
			byte[] keyBytes = Base64Utils.decoder(publicKey).getBytes();
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // 取得公钥  
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			Key key = keyFactory.generatePrivate(keySpec);
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, key);
			return new String(cipher.doFinal(content.getBytes()));
		}catch(Exception e){
			throw e;
		}
	}

	
	/**
	 * RSA私钥加密
	 * </br>Created on 2016年4月20日
	 * @param content
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static String encryptRSAWithPrivateKey(String content,String privateKey) throws Exception{
		try{
			byte[] keyBytes = Base64Utils.decoder(privateKey).getBytes();
			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); // 取得私钥  
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			Key key = keyFactory.generatePrivate(keySpec);
			Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
			cipher.init(Cipher.ENCRYPT_MODE, key);
			return new String(cipher.doFinal(content.getBytes()));
		}catch(Exception e){
			throw e;
		}
	}
	
	/**
	 * RSA公钥解密
	 * </br>Created on 2016年4月20日
	 * @param content
	 * @param publicKey
	 * @return
	 * @throws Exception
	 */
	public static String decryptWithPublicKey(String content, String publicKey) throws Exception {  
		try{
			// 对密钥解密  
	        byte[] keyBytes = Base64Utils.decoder(publicKey).getBytes();  
	        // 取得公钥  
	        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
	        KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
	        Key key = keyFactory.generatePublic(x509KeySpec);  
	        // 对数据解密  
	        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.DECRYPT_MODE, key);  
	        return new String(cipher.doFinal(content.getBytes()));  
		}catch(Exception e){
			throw e;
		}
    } 
	
	/**
	 * RSA私钥解密
	 * </br>Created on 2016年4月20日
	 * @param content
	 * @param privateKey
	 * @return
	 * @throws Exception
	 */
	public static String decryptWithPrivateKey(String content, String privateKey) throws Exception {  
        try{
			// 对密钥解密  
	        byte[] keyBytes = Base64Utils.decoder(privateKey).getBytes();
	        // 取得私钥  
	        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
	        KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
	        Key key = keyFactory.generatePrivate(pkcs8KeySpec);  
	        // 对数据解密  
	        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.DECRYPT_MODE, key);  
	        return new String(cipher.doFinal(content.getBytes()));
        }catch(Exception e){
			throw e;
        }
    }
	
	
	/**
	 * 私钥签名
	 * TODO
	 * </br>Created on 2016年4月20日
	 * @param data 原字符串
	 * @param privateKey 私钥
	 * @return 签名
	 * @throws Exception
	 */
	public static byte[] sign(byte[] data,PrivateKey privateKey) throws Exception{
		try{
			Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
			signature.initSign(privateKey);
			signature.update(data);
			return signature.sign();
		}catch(Exception e){
			throw e;
		}
	}
	

	/**
	 * 公钥验签
	 * </br>Created on 2016年4月20日
	 * @param data 原字符串
	 * @param sign 签名结果
	 * @param publicKey 公钥
	 * @return 验签结果
	 * @throws Exception
	 */
	public static boolean checkSign(byte[] data,byte[] sign,PublicKey publicKey) throws Exception{
		try{
			Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
			signature.initVerify(publicKey);
			signature.update(data);
			return signature.verify(sign);
		}catch(Exception e){
			throw e;
		}
	}
	
	private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";//签名算法

}
